﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using System;
using System.Collections.Concurrent;

namespace VisionCloud.Utility
{
    public class ConfigHelper
    {
        private static ConcurrentDictionary<string, object> dic = new ConcurrentDictionary<string, object>();

        /// <summary>
        /// 配置
        /// </summary>
        public static IConfiguration Configuration { get; set; }

        /// <summary>
        /// 初始化配置
        /// </summary>
        /// <param name="configuration"></param>
        public static void InitConfiguration(IConfiguration configuration) => Configuration = configuration;

        /// <summary>
        /// 获取程序配置
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetValue<T>(string key) => Configuration.GetValue<T>(key);

        /// <summary>
        /// 获取程序配置（通过读取对应环境变量的配置文件）
        /// </summary>
        /// <remarks>此方法有隐藏Bug：比如服务器的环境变量和程序设置的环境变量不一致的时候，读取到的是服务器的环境变量</remarks>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetValueByEnvironment<T>(string key)
        {
            var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
            return GetValue<T>(AppContext.BaseDirectory, $"appsettings.{env}.json", key);
        }

        public static T GetValue<T>(string baseDir, string fileName, string key)
        {
            if (dic.ContainsKey(key))
            {
                return (T)dic[key];
            }
            var jsonConfigSource = new JsonConfigurationSource { Path = fileName, Optional = false, ReloadOnChange = true };
            var config = new ConfigurationBuilder()
                .SetBasePath(baseDir)
                .Add(jsonConfigSource)
                .Build();
            jsonConfigSource = null;
            var result = config.GetSection(key).Get<T>();
            if (!dic.ContainsKey(key))
            {
                dic.AddOrUpdate(key, result, (tkey, oldValue) => result);
            }
            return result;
        }
    }
}